/*
** YM2610 interface (not YM2610B though)
**
** The YM2610 is found on Neo Geo games and some Taito systems.
*/

#include "opnseries.hpp"


extern "C" {
#include "fm.h"
};

extern "C" void ym2610_update_request(void *param) {
	printf("[ym2610] update request called, not doing anything.\n");
}

static const char* channelNames[15] = {
	"FM Channel 1",
	"FM Channel 2",
	"FM Channel 3",
	"FM Channel 4",
	"PSG Channel 1",
	"PSG Channel 2",
	"PSG Channel 3",
	"ADPCM Channel 1",
	"ADPCM Channel 2",
	"ADPCM Channel 3",
	"ADPCM Channel 4",
	"ADPCM Channel 5",
	"ADPCM Channel 6",
	"ADPCM Channel 7",
};

// Channel mute callbacks.
void YM2610::muteFm1(int status) {
	this->channelMask[0] = status;
}
void YM2610::muteFm2(int status) {
	this->channelMask[1] = status;
}
void YM2610::muteFm3(int status) {
	this->channelMask[2] = status;
}
void YM2610::muteFm4(int status) {
	this->channelMask[3] = status;
}
void YM2610::mutePsg1(int status) {
	this->channelMask[4] = status;
}
void YM2610::mutePsg2(int status) {
	this->channelMask[5] = status;
}
void YM2610::mutePsg3(int status) {
	this->channelMask[6] = status;
}

void YM2610::mutePcm1(int status) {

}
void YM2610::mutePcm2(int status) {

}
void YM2610::mutePcm3(int status) {

}
void YM2610::mutePcm4(int status) {

}
void YM2610::mutePcm5(int status) {

}
void YM2610::mutePcm6(int status) {

}
void YM2610::mutePcm7(int status) {

}

// Access channel mute callbacks
int YM2610::getChannels(char* names[], void (*mutecallbacks[])(int)) {
	names = channelNames;

	mutecallbacks[0] = this->muteFm1;
	mutecallbacks[1] = this->muteFm2;
	mutecallbacks[2] = this->muteFm3;
	mutecallbacks[3] = this->muteFm4;
	mutecallbacks[4] = this->mutePsg1;
	mutecallbacks[5] = this->mutePsg2;
	mutecallbacks[6] = this->mutePsg3;

	// Return number of channels to setup
	return 14;
}

int YM2610::init(unsigned int clock, unsigned int srate) {
//	smse2k.allocChannels(channelNames,15);

	// create the PSG


	//

	return 1; // unimplemented :|
}

unsigned int YM2610::run(short* buf, unsigned int len) {
	short** fakeBuffers = {
		buf,   // left
		buf+1, // rights
	};
	if (!this->chip) return 0;

	// We have yet to see if this works right...
	ym2610b_update_one(this->chip,fakeBuffers,len);

	return len;
}
